﻿using Microsoft.Win32;
using Spire.Pdf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Printing;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Xps.Packaging;

namespace DPrint
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string docxFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "_res", "1.docx");
        private string pdfFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "_res", "1.pdf");
        private string xpsFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "_res", "1.xps");
        private string jpgFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "_res", "1.jpg");

        public MainWindow()
        {
            InitializeComponent();

            documentViewerLoad();
        }

        private void documentViewerLoad()
        {
            XpsDocument doc = new XpsDocument(xpsFile, FileAccess.Read);
            documentViewer1.Document = doc.GetFixedDocumentSequence();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = sender as MenuItem;
            switch (menuItem.Header)
            {
                case "Jpg 1":
                    printJpg();
                    break;
                case "Pdf 1":
                    printPdf();
                    break;
                case "Pdf 2":
                    printPdf2();
                    break;
                case "Xps 1":
                    printXps();
                    break;
                case "Xps 2":
                    printXps2();
                    break;
                case "Docx 1":
                    printDocx();
                    break;
                case "Docx 2":
                    printDocx2();
                    break;
                case "Common 1":
                    PrintWholeDocument(xpsFile, false);
                    break;
                case "Process 1":
                    printByProcess();
                    break;
                default:
                    break;
            }
        }

        private void printJpg()
        {
            PrintDocument printDocument = new PrintDocument();
            printDocument.DocumentName = jpgFile;
            printDocument.PrintPage += (sender, e) =>
            {
                var settings = new PrinterSettings();
                printDocument.PrinterSettings = settings;
            };
            printDocument.Print();
        }

        private void printPdf()
        {
            PrintDocument printDocument = new PrintDocument();
            printDocument.DocumentName = pdfFile;
            printDocument.PrintPage += (sender, e) =>
            {
                var settings = new PrinterSettings();
                printDocument.PrinterSettings = settings;
            };
            printDocument.Print();
        }

        private void printPdf2()
        {
            PdfDocument pdfDocument = new PdfDocument(pdfFile);
            PrintDocument printDocument = new PrintDocument();
            printDocument.PrintPage += (sender, e) =>
            {
                //Page page = pdfDocument.PageCount > e.PageSettings.PrinterSettings.ToPageNumber(e.PageNumber)
                //    ? pdfDocument.Pages[e.PageSettings.PrinterSettings.ToPageNumber(e.PageNumber) - 1]
                //    : null;

                var page = pdfDocument.Pages[0];

                if (page != null)
                {
                    //Bitmap image = page.Render((int)e.MarginBounds.Width, (int)e.MarginBounds.Height,
                    //    (int)e.MarginBounds.Left, (int)e.MarginBounds.Top, false);

                    Bitmap image = null;

                    e.Graphics.DrawImage(image, e.MarginBounds.Location);
                }

                //e.HasMorePages = e.PageSettings.PrinterSettings.ToPageNumber(e.PageNumber) < pdfDocument.PageCount;
                e.HasMorePages = true;

            };
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() == true)
            {
                // 设置打印文档大小和打印机名称等参数
                printDocument.DefaultPageSettings.PaperSize = new PaperSize("Custom", 800, 1100);
                printDocument.DefaultPageSettings.PrinterSettings.PrinterName = printDialog.PrintQueue.FullName;

                // 启动打印操作
                printDocument.Print();
            }
        }

        private void printXps()
        {
            PrintDocument printDocument = new PrintDocument();
            printDocument.DocumentName = xpsFile;
            printDocument.PrintPage += (sender, e) =>
            {
                var settings = new PrinterSettings();
                printDocument.PrinterSettings = settings;
            };
            printDocument.Print();
        }

        private void printXps2()
        {
            // 创建PrintDialog对象
            PrintDialog printDialog = new PrintDialog();
            // 显示打印对话框并获取用户的打印设置
            bool? result = printDialog.ShowDialog();
            if (result == true)
            {
                // 获取分页器
                DocumentPaginator paginator = ((IDocumentPaginatorSource)documentViewer1.Document).DocumentPaginator;
                // 打印文档
                printDialog.PrintDocument(paginator, "Print Document");
            }
        }

        private void printDocx()
        {
            var templateFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "template", "report.docx");


            PrintDocument printDocument = new PrintDocument();
            printDocument.DocumentName = templateFile;
            printDocument.PrintPage += (sender, e) =>
            {
                var settings = new PrinterSettings();
                printDocument.PrinterSettings = settings;
            };
            printDocument.Print();
        }

        private void printDocx2()
        {
            PrintWholeDocument(xpsFile, false);
        }

        private void printByProcess()
        {
            try
            {
                var pr = new Process
                {
                    StartInfo =
                    {
                        FileName = pdfFile,
                        CreateNoWindow = true,
                        WindowStyle = ProcessWindowStyle.Hidden,
                        Verb = "Print"
                    }
                };
                pr.StartInfo.UseShellExecute = true;
                pr.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /// <summary>
        /// Print all pages of an XPS document.
        /// Optionally, hide the print dialog window.
        /// </summary>
        /// <param name="xpsFilePath">Path to source XPS file</param>
        /// <param name="hidePrintDialog">Whether to hide the print dialog window (shown by default)</param>
        /// <returns>Whether the document printed</returns>
        public static bool PrintWholeDocument(string xpsFilePath, bool hidePrintDialog = false)
        {
            // Create the print dialog object and set options.
            PrintDialog printDialog = new();

            if (!hidePrintDialog)
            {
                // Display the dialog. This returns true if the user presses the Print button.
                bool? isPrinted = printDialog.ShowDialog();
                if (isPrinted != true)
                    return false;
            }

            // Print the whole document.
            try
            {
                // Open the selected document.
                XpsDocument xpsDocument = new(xpsFilePath, FileAccess.Read);

                // Get a fixed document sequence for the selected document.
                FixedDocumentSequence fixedDocSeq = xpsDocument.GetFixedDocumentSequence();

                // Create a paginator for all pages in the selected document.
                DocumentPaginator docPaginator = fixedDocSeq.DocumentPaginator;

                // Print to a new file.
                printDialog.PrintDocument(docPaginator, $"Printing {System.IO.Path.GetFileName(xpsFilePath)}");

                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);

                return false;
            }
        }
    }
}
